import { api } from '@/servers/api'
import { postFile } from '@/servers/http'
import { ImageUploader, Toast } from 'antd-mobile'
import type { ImageUploaderProps } from 'antd-mobile/es/components/image-uploader'
import React, { useState, useEffect } from 'react'
import pressImg from './utils/pressImg'
/**
 * queryParams  object  接口请求参数
 * maxSize      number  限制上传最大大小 单位m 默认 20
 *
 * 注意：
 * maxCount 必须配合 value 使用！！！
 */
export interface BaseUploadInterface extends Omit<ImageUploaderProps, 'upload' | 'beforeUpload'> {
    queryParams?: object
    maxSize?: number
    upload?: ImageUploaderProps['upload']
    beforeUpload?: (file: File) => Promise<File>
    noPressImg?: boolean
}

function BaseUpload({ children, beforeUpload, queryParams = {}, maxSize = 20, value, maxCount = 100, noPressImg, ...restProps }: BaseUploadInterface) {
    const [bShowUpload, setBShowUploader] = useState(true)

    /** 图片压缩 */
    const fnCompress = (file: File): Promise<File> =>
        new Promise((resolve, reject) =>
            pressImg({
                file,
                targetSize: 4 * 1024 * 1024,
                quality: 0.5,
                width: 600,
                succ: async (resultFile: File) => {
                    // 如果不是null就是压缩成功
                    if (resultFile) {
                        if (beforeUpload) {
                            await beforeUpload(resultFile).then(res => {
                                resolve(res)
                            })
                        } else {
                            resolve(resultFile)
                        }
                    }
                    reject(new Error('压缩失败'))
                },
            }),
        )

    /** 上传预处理 */
    const fnBeforeUpload = (file: File): Promise<File> => {
        // const { accept } = restProps
        if (file.size > maxSize * 1024 * 1024) {
            const text = file.type.indexOf('image') === -1 ? '文件' : '图片'
            Toast.show(`请选择小于 ${maxSize}M 的${text}`)
            return Promise.reject()
        }

        /** 如果设置上传类型 不进行图压缩 */
        if (noPressImg || file.type.indexOf('image') === -1) {
            return Promise.resolve(file)
        }

        return fnCompress(file).then(res => {
            /** 控制按钮显示 */
            if ((value?.length || 0) + 1 >= maxCount) {
                setBShowUploader(false)
            }
            return Promise.resolve(res)
        })
    }

    /** 上传事件 * */
    const fnUploadImg = (file: File) => {
        Toast.show({
            icon: 'loading',
            content: '上传中…',
            maskClickable: false,
            duration: 0,
        })
        return postFile(api.uploads, {
            file,
            ...queryParams,
        })
            .then(res => {
                const { data, status } = res || {}
                Toast.clear()
                if (status >= 200 && status < 400) {
                    const { url, ext, name } = data || ({} as any)
                    return Promise.resolve({ url, extra: data, name: `${name}.${ext}` })
                }
                Toast.show('上传失败')
                return Promise.reject(new Error('上传失败'))
            })
            .catch(() => {
                /** 兼容立刻关闭接口错误提示 */
                setTimeout(() => {
                    Toast.clear()
                }, 1500)
                if ((value?.length || 0) >= maxCount) {
                    setBShowUploader(false)
                } else {
                    setBShowUploader(true)
                }
                return Promise.reject(new Error())
            })
    }

    useEffect(() => {
        /** 处理上传失败 不显示但是占用 maxCount 数量 */
        if (value && value?.length >= maxCount) {
            setBShowUploader(false)
        } else {
            setBShowUploader(true)
        }
    }, [value, maxCount])

    return (
        <ImageUploader upload={fnUploadImg} value={value} {...restProps} beforeUpload={fnBeforeUpload} showFailed={false} maxCount={0} showUpload={bShowUpload}>
            {children}
        </ImageUploader>
    )
}

export default BaseUpload
